package logica.persistencia;

import java.util.List;

import logica.Atributo;
import logica.AtributoCompuesto;
import logica.AtributoSimple;

import org.jdom.Element;

import vista.objetos.AtributoGraficable;
import vista.objetos.AtributoGraficableCompuesto;
import vista.objetos.EntidadGraficable;
import vista.objetos.GraficableConEtiqueta;
import vista.objetos.GraficableConEtiquetaConAtributos;
import xml.ConstantesXml;
import xml.XMLManager;

public class AtributoGraficablePersistente extends
		GraficableConEtiquetaPersistente {
		Element elementoAtributo;

	public AtributoGraficablePersistente(
			GraficableConEtiqueta _graficableConEtiqueta, Element elementoAtributo) {
		super(_graficableConEtiqueta);
		this.elementoAtributo = elementoAtributo;
	}
	public AtributoGraficablePersistente(
			GraficableConEtiqueta _graficableConEtiqueta) {
		super(_graficableConEtiqueta);
	}

	@Override
	public void serializar() {
		AtributoGraficable atribG = (AtributoGraficable)this.getGraficableConEtiqueta();
		Atributo atributo = atribG.getAtributo();
		super.serializarGenerico(atributo, elementoAtributo);
		this.getElementoPadre().addContent(elementoAtributo);
	}

	@Override
	public void hidratar() {
		super.hidratarGenerico(this.getElementoGraficable());
	}
	
	public static void serializarAtributos(List<AtributoGraficable> graficables, Element padre) {
		Element listaAtributos = new Element(ConstantesXml.LISTA_ATRIBUTOS);
		
		for (AtributoGraficable atrib : graficables){
			Element elementoAtributo = null;
			Atributo atributo = atrib.getAtributo();
	
			if (atributo instanceof AtributoSimple) {
				elementoAtributo = new Element (ConstantesXml.ELEMENTO_ATRIBUTO_SIMPLE);
				AtributoGraficablePersistente atribGP = new AtributoGraficablePersistente(atrib, elementoAtributo);
				atribGP.setElementoPadre(listaAtributos);
				atribGP.serializar();		
			}
			else if (atributo instanceof AtributoCompuesto) {
				AtributoGraficableCompuesto atribGC = (AtributoGraficableCompuesto)atrib; 
				elementoAtributo = new Element (ConstantesXml.ELEMENTO_ATRIBUTO_COMPUESTO);
				AtributoGraficablePersistente atribGP = new AtributoGraficablePersistente(atrib, elementoAtributo);
				atribGP.setElementoPadre(listaAtributos);
				atribGP.serializar();
				List<AtributoGraficable> atribs = atribGC.getAtributosGraficables();
				AtributoGraficablePersistente.serializarAtributos(atribs, elementoAtributo);
				
			}	
		}
		if (graficables != null && graficables.size() > 0) {
			padre.addContent(listaAtributos);

		}
	}
	
	private static AtributoGraficable obtenerAtributoGraficable(List<AtributoGraficable> lista, Atributo atrib) {
		for (AtributoGraficable atributoG : lista) {
			if (atributoG.getAtributo() == atrib) {
				return atributoG;
			}
		}
		return null;
	}
	static void hidratarAtributos(List<AtributoGraficable> atributosGraficables, GraficableConEtiqueta graficable, Element elementoGraficable) {
		Element elementListaAtributos = elementoGraficable.getChild(ConstantesXml.LISTA_ATRIBUTOS);
		
		if (elementListaAtributos != null) {
			@SuppressWarnings("unchecked")
			List <Element> elementListaAtributosSimples = elementListaAtributos.getChildren(ConstantesXml.ELEMENTO_ATRIBUTO_SIMPLE);
				
				
			for (Element elementoAtributo: elementListaAtributosSimples) {
				String clave = elementoAtributo.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
				Atributo atrib = (Atributo)XMLManager.getInstance().objtenerObjetoDiagramaConClave(clave);
					
				AtributoGraficable atribG = AtributoGraficablePersistente.obtenerAtributoGraficable(atributosGraficables, atrib);
					
			
				if (atribG != null){
					//Hasheo el elemento para poder obtenerlo después a través del id
					XMLManager.getInstance().hashObjetoDiagramaRepConClave(clave, atribG);
						
					AtributoGraficablePersistente atribGP = new AtributoGraficablePersistente(atribG);
					atribGP.setElementoGraficable(elementoAtributo);
					atribGP.hidratar();
					if (graficable instanceof AtributoGraficableCompuesto) {
						AtributoGraficableCompuesto graf = (AtributoGraficableCompuesto) graficable;
						if (!graf.getAtributosGraficables().contains(atribG))
							graf.agregarAtributoGraficable(atribG);
					}
					else if (graficable instanceof GraficableConEtiquetaConAtributos) {
						GraficableConEtiquetaConAtributos graf = (GraficableConEtiquetaConAtributos)graficable;
						if (!graf.getAtributos().contains(atribG))
							graf.getAtributos().add(atribG);
					}
				}
			}
			
			@SuppressWarnings("unchecked")
			List <Element> elementListaAtributosCompuestos = elementListaAtributos.getChildren(ConstantesXml.ELEMENTO_ATRIBUTO_COMPUESTO);
			
		   			
			for (Element elementoAtributo: elementListaAtributosCompuestos) {
				
				String clave = elementoAtributo.getAttributeValue(ConstantesXml.ATRIBUTO_ID_OBJETO);
				Atributo atrib = (Atributo)XMLManager.getInstance().objtenerObjetoDiagramaConClave(clave);
					
				AtributoGraficableCompuesto atribG = (AtributoGraficableCompuesto)AtributoGraficablePersistente.obtenerAtributoGraficable(atributosGraficables, atrib);
				
				if (atribG != null){
					
					//Hasheo el elemento para poder obtenerlo después a través del id
					XMLManager.getInstance().hashObjetoDiagramaConClave(clave, atribG);
					AtributoGraficablePersistente atribGP = new AtributoGraficablePersistente(atribG);
					atribGP.setElementoGraficable(elementoAtributo);
					List<AtributoGraficable> atributos = atribG.getAtributosGraficables();
					
					hidratarAtributos(atributos, atribG, elementoAtributo);	
					atribGP.hidratar();
					if (graficable instanceof EntidadGraficable) {
						EntidadGraficable graf = (EntidadGraficable)graficable;
						if (!graf.getAtributos().contains(atribG))
							graf.getAtributos().add(atribG);
					}
				}
			}
			
		
		}	
			
			
		
	}

}
